using BuildingBlocks.Application.Messaging;
using BuildingBlocks.Domain;
using BuildingBlocks.Application.Authentication;
using Ordering.Application.Abstractions.Persistence;
using Ordering.Application.Orders.Contracts;
using Ordering.Application.Orders.GetOrders;
using Ordering.Domain.Orders;

namespace Ordering.Application.Orders.CreateOrder;

internal sealed class CreateOrderCommandHandler(
    IOrderRepository repository,
    IUnitOfWork unitOfWork,
    ICurrentUser currentUser)
    : ICommandHandler<CreateOrderCommand, OrderResponse>
{
    public async ValueTask<Result<OrderResponse>> Handle(CreateOrderCommand request, CancellationToken cancellationToken)
    {
        if (request.Items.Count == 0)
        {
            return Result.Failure<OrderResponse>(OrderErrors.EmptyItems);
        }

        var items = request.Items
            .Select(item => new OrderItem(
                item.ProductId,
                item.ProductName,
                item.UnitPrice,
                item.Quantity <= 0 ? 1 : item.Quantity))
            .ToList();

        var order = new Order(
            currentUser.UserId,
            items,
            request.ShippingAddress,
            request.Notes);

        await repository.AddAsync(order, cancellationToken);
        await unitOfWork.SaveChangesAsync(cancellationToken);

        return Result.Success(order.ToResponse());
    }
}
